using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using Microsoft.WowAddonStudio.FrameXml.Components;
using Microsoft.WowAddonStudio.Tests.Common.Mocks;

namespace Microsoft.WowAddonStudio.FrameXml.Editor.Test.Mocks
{
	/// <summary>
	/// Provides an mock object for managing designer transactions and components.
	/// </summary>
	public class MockDesignerHost : IDesignerHost
	{
		#region IDesignerHost Members

#pragma warning disable 67 // Disable warning CS0067: The event '...' is never used

		/// <summary>
		/// Occurs when this designer is activated.
		/// </summary>
		public event EventHandler Activated;
		/// <summary>
		/// Occurs when this designer is deactivated.
		/// </summary>
		public event EventHandler Deactivated;
		/// <summary>
		/// Occurs when this designer completes loading its document.
		/// </summary>
		public event EventHandler LoadComplete;
		/// <summary>
		/// Adds an event handler for the <see cref="E:System.ComponentModel.Design.IDesignerHost.TransactionClosed"/> event.
		/// </summary>
		public event DesignerTransactionCloseEventHandler TransactionClosed;
		/// <summary>
		/// Adds an event handler for the <see cref="E:System.ComponentModel.Design.IDesignerHost.TransactionClosing"/> event.
		/// </summary>
		public event DesignerTransactionCloseEventHandler TransactionClosing;
		/// <summary>
		/// Adds an event handler for the <see cref="E:System.ComponentModel.Design.IDesignerHost.TransactionOpened"/> event.
		/// </summary>
		public event EventHandler TransactionOpened;
		/// <summary>
		/// Adds an event handler for the <see cref="E:System.ComponentModel.Design.IDesignerHost.TransactionOpening"/> event.
		/// </summary>
		public event EventHandler TransactionOpening;

#pragma warning restore 67

        private readonly UiControl rootControl;
		private readonly SimpleTestServiceLocator locator;


		/// <summary>
		/// Initializes a new instance of the <see cref="MockDesignerHost"/> class.
		/// </summary>
		/// <param name="locator">The locator.</param>
		/// <param name="rootControl">The root control.</param>
		public MockDesignerHost(SimpleTestServiceLocator locator, UiControl rootControl)
		{
			this.locator = locator;
			this.rootControl = rootControl;
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="MockDesignerHost"/> class.
		/// </summary>
		/// <param name="locator">The locator.</param>
		public MockDesignerHost(SimpleTestServiceLocator locator):this(locator, new UiControl())
		{
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="MockDesignerHost"/> class.
		/// </summary>
		/// <param name="rootControl">The root control.</param>
		public MockDesignerHost(UiControl rootControl)
			: this(null, rootControl)
		{
		}

		/// <summary>
		/// Activates the designer that this host is hosting.
		/// </summary>
		public void Activate()
		{
			throw new NotImplementedException();
		}

		/// <summary>
		/// Creates a component of the specified type and adds it to the design document.
		/// </summary>
		/// <param name="componentClass">The type of the component to create.</param>
		/// <returns>The newly created component.</returns>
		public IComponent CreateComponent(Type componentClass)
		{
			throw new NotImplementedException();
		}

		/// <summary>
		/// Creates a component of the specified type and name, and adds it to the design document.
		/// </summary>
		/// <param name="componentClass">The type of the component to create.</param>
		/// <param name="name">The name for the component.</param>
		/// <returns>The newly created component.</returns>
		public IComponent CreateComponent(Type componentClass, string name)
		{
			throw new NotImplementedException();
		}

		/// <summary>
		/// Creates a <see cref="T:System.ComponentModel.Design.DesignerTransaction"/> that can encapsulate event sequences to improve performance and enable undo and redo support functionality.
		/// </summary>
		/// <returns>
		/// A new instance of <see cref="T:System.ComponentModel.Design.DesignerTransaction"/>. When you complete the steps in your transaction, you should call <see cref="M:System.ComponentModel.Design.DesignerTransaction.Commit"/> on this object.
		/// </returns>
		public DesignerTransaction CreateTransaction()
		{
			throw new NotImplementedException();
		}

		/// <summary>
		/// Creates a <see cref="T:System.ComponentModel.Design.DesignerTransaction"/> that can encapsulate event sequences to improve performance and enable undo and redo support functionality, using the specified transaction description.
		/// </summary>
		/// <param name="description">A title or description for the newly created transaction.</param>
		/// <returns>
		/// A new <see cref="T:System.ComponentModel.Design.DesignerTransaction"/>. When you have completed the steps in your transaction, you should call <see cref="M:System.ComponentModel.Design.DesignerTransaction.Commit"/> on this object.
		/// </returns>
		public DesignerTransaction CreateTransaction(string description)
		{
			throw new NotImplementedException();
		}

		/// <summary>
		/// Destroys the specified component and removes it from the designer container.
		/// </summary>
		/// <param name="component">The component to destroy.</param>
		public void DestroyComponent(IComponent component)
		{
			throw new NotImplementedException();
		}

		/// <summary>
		/// Gets the designer instance that contains the specified component.
		/// </summary>
		/// <param name="component">The <see cref="T:System.ComponentModel.IComponent"/> to retrieve the designer for.</param>
		/// <returns>
		/// An <see cref="T:System.ComponentModel.Design.IDesigner"/>, or null if there is no designer for the specified component.
		/// </returns>
		public IDesigner GetDesigner(IComponent component)
		{
			throw new NotImplementedException();
		}

		/// <summary>
		/// Gets an instance of the specified, fully qualified type name.
		/// </summary>
		/// <param name="typeName">The name of the type to load.</param>
		/// <returns>
		/// The type object for the specified type name, or null if the type cannot be found.
		/// </returns>
		public Type GetType(string typeName)
		{
			throw new NotImplementedException();
		}

		/// <summary>
		/// Gets a value indicating whether the designer host is currently loading the document.
		/// </summary>
		/// <value></value>
		/// <returns>true if the designer host is currently loading the document; otherwise, false.</returns>
		public bool Loading
		{
			get { throw new NotImplementedException(); }
		}

		/// <summary>
		/// Gets a value indicating whether the designer host is currently in a transaction.
		/// </summary>
		/// <value></value>
		/// <returns>true if a transaction is in progress; otherwise, false.</returns>
		public bool InTransaction
		{
			get { throw new NotImplementedException(); }
		}

		/// <summary>
		/// Gets the container for this designer host.
		/// </summary>
		/// <value></value>
		/// <returns>The <see cref="T:System.ComponentModel.IContainer"/> for this host.</returns>
		public IContainer Container
		{
			get { throw new NotImplementedException(); }
		}

		/// <summary>
		/// Gets the instance of the base class used as the root component for the current design.
		/// </summary>
		/// <value></value>
		/// <returns>The instance of the root component class.</returns>
		public IComponent RootComponent
		{
			get { return rootControl; }
		}

		/// <summary>
		/// Gets the fully qualified name of the class being designed.
		/// </summary>
		/// <value></value>
		/// <returns>The fully qualified name of the base component class.</returns>
		public string RootComponentClassName
		{
			get { return rootControl.GetType().Name; }
		}

		/// <summary>
		/// Gets the description of the current transaction.
		/// </summary>
		/// <value></value>
		/// <returns>A description of the current transaction.</returns>
		public string TransactionDescription
		{
			get { throw new NotImplementedException(); }
		}

		#endregion

		#region IServiceContainer Members

		/// <summary>
		/// Adds the specified service to the service container.
		/// </summary>
		/// <param name="serviceType">The type of service to add.</param>
		/// <param name="serviceInstance">An instance of the service type to add. This object must implement or inherit from the type indicated by the <paramref name="serviceType"/> parameter.</param>
		public void AddService(Type serviceType, object serviceInstance)
		{
			throw new NotImplementedException();
		}

		/// <summary>
		/// Adds the specified service to the service container, and optionally promotes the service to any parent service containers.
		/// </summary>
		/// <param name="serviceType">The type of service to add.</param>
		/// <param name="serviceInstance">An instance of the service type to add. This object must implement or inherit from the type indicated by the <paramref name="serviceType"/> parameter.</param>
		/// <param name="promote">true to promote this request to any parent service containers; otherwise, false.</param>
		public void AddService(Type serviceType, object serviceInstance, bool promote)
		{
			throw new NotImplementedException();
		}

		/// <summary>
		/// Adds the specified service to the service container.
		/// </summary>
		/// <param name="serviceType">The type of service to add.</param>
		/// <param name="callback">A callback object that is used to create the service. This allows a service to be declared as available, but delays the creation of the object until the service is requested.</param>
		public void AddService(Type serviceType, ServiceCreatorCallback callback)
		{
			throw new NotImplementedException();
		}

		/// <summary>
		/// Adds the specified service to the service container, and optionally promotes the service to parent service containers.
		/// </summary>
		/// <param name="serviceType">The type of service to add.</param>
		/// <param name="callback">A callback object that is used to create the service. This allows a service to be declared as available, but delays the creation of the object until the service is requested.</param>
		/// <param name="promote">true to promote this request to any parent service containers; otherwise, false.</param>
		public void AddService(Type serviceType, ServiceCreatorCallback callback, bool promote)
		{
			throw new NotImplementedException();
		}

		/// <summary>
		/// Removes the specified service type from the service container.
		/// </summary>
		/// <param name="serviceType">The type of service to remove.</param>
		public void RemoveService(Type serviceType)
		{
			throw new NotImplementedException();
		}

		/// <summary>
		/// Removes the specified service type from the service container, and optionally promotes the service to parent service containers.
		/// </summary>
		/// <param name="serviceType">The type of service to remove.</param>
		/// <param name="promote">true to promote this request to any parent service containers; otherwise, false.</param>
		public void RemoveService(Type serviceType, bool promote)
		{
			throw new NotImplementedException();
		}

		#endregion

		#region IServiceProvider Members

		/// <summary>
		/// Gets the service object of the specified type.
		/// </summary>
		/// <param name="serviceType">An object that specifies the type of service object to get.</param>
		/// <returns>
		/// A service object of type <paramref name="serviceType"/>.-or- null if there is no service object of type <paramref name="serviceType"/>.
		/// </returns>
		public object GetService(Type serviceType)
		{
			return locator.GetService(serviceType);
		}

		#endregion
	}
}